/******************************************************************************

    Simple Authentication and Authorisation System (SAAS)

    saas-test-group-info.c

    Copyright (C) 2011  Josh Goes


    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.

    If you require a mailing address for this software, please send your
    mail to the following address:
        SAAS
        GPO Box 2973
        BRISBANE QLD 4001
        AUSTRALIA

******************************************************************************/


#include "saas.h"
#include "tests.h"

#include <stdio.h>
#include <syslog.h>
#include <string.h>
#include <stdlib.h>


char     opt_groupname[SAAS_MAX_GROUPNAME_LEN];
uint32_t opt_gid = 0;
uint8_t  opt_members = 0;
uint8_t  opt_all_members = 0;
uint8_t  opt_log_level = LOG_INFO;
uint8_t  show_help = 0;


struct st_saas_test_opt opts[] = {
	{ "by-groupname" , "n"  , 1 , NULL , &opt_groupname   , SAAS_TEST_VAR_TYPE_STR    , 0         , NULL , sizeof( opt_groupname ) },
	{ "by-gid"       , "i"  , 1 , NULL , &opt_gid         , SAAS_TEST_VAR_TYPE_UINT32 , 0         , NULL , 0                       },
	{ "members"      , "m"  , 0 , NULL , &opt_members     , SAAS_TEST_VAR_TYPE_UINT8  , 1         , NULL , 0                       },
	{ "all-members"  , "a"  , 0 , NULL , &opt_all_members , SAAS_TEST_VAR_TYPE_UINT8  , 1         , NULL , 0                       },
	{ "debug"        , "d"  , 0 , NULL , &opt_log_level   , SAAS_TEST_VAR_TYPE_UINT8  , LOG_DEBUG , NULL , 0                       },
	{ "quiet"        , "q"  , 0 , NULL , &opt_log_level   , SAAS_TEST_VAR_TYPE_UINT8  , LOG_CRIT  , NULL , 0                       },
	{ "help"         , "h"  , 0 , NULL , &show_help       , SAAS_TEST_VAR_TYPE_UINT8  , 1         , NULL , 0                       },
	{ NULL           , NULL , 0 , NULL , NULL             , 0                         , 0         , NULL , 0                       }
};



int main( int argc , char **argv )
{
	memset( opt_groupname , 0 , sizeof( opt_groupname ) );
	if ( saas_get_opts( opts , argc , argv ) != SAAS_OP_SUCCESS )
	{
		printf( "%s: error: could not parse arguments\n" , argv[0] );
		return 2;
	}
	if ( show_help == 1 || argc == 1 )
	{
		printf( "%s: usage:  <--by-gid gid|--by-groupname groupname|--help> [--members|--all-members|--debug|--quiet]\n\n" , argv[0] );
		printf(
			"This program tests the SAAS system by requesting group information by either\nGID or groupname.\n\n"
			"    --by-gid gid              Specifies the GID that is being searched.\n"
			"    -i       gid\n\n"
			"    --by-groupname groupname  Specifies the Groupname that is being searched.\n"
			"    -n             groupname\n\n"
			"    --members                 Include membership information in the response.\n"
			"    -m\n\n"
			"    --all-members             Include all membership information in the\n"
			"                              response, regardless of whether the member is a\n"
			"                              direct member of the group, or is a member by\n"
			"                              group-by-group relation.\n"
			"    -a\n\n"
			"    --debug                   Enable debugging mode. This products a LOT of\n"
			"                              output.\n"
			"    -d\n\n"
			"    --quiet                   Allow only the utmost critical errors to be\n"
			"                              displayed.\n"
			"    -q\n\n"
			"    --help                    Display this usage message.\n"
			"    -h\n\n"
		);
		return 1;
	}

	if ( strlen( opt_groupname ) == 0 && opt_gid == 0 )
	{
		printf( "%s: error: you must specify at least a groupname or a GID. see `%s --help` for details.\n" , argv[0] , argv[0] );
		return 2;
	}

	// ok checks are done.  on with the show.
	saas_t     inst;
	uint16_t   ret;

	if ( opt_log_level == LOG_DEBUG )
		printf( "spawning new SAAS instance with saas_init()...\n" );

	ret = saas_init( &inst , NULL , opt_log_level , SAAS_LOG_STDOUT , 0 , NULL );
	if ( ret != SAAS_OP_SUCCESS )
	{
		printf( "error whilst calling saas_init(): (%d) %s\n" , ret , saaserror( ret ) );
		return 3;
	}


	if ( opt_log_level == LOG_DEBUG )
		printf( "SAAS Instance debugging data:\n" );
	saas_dump( &inst , " - " );

	saas_group_info_t  *gi;

	if ( opt_log_level == LOG_DEBUG )
		printf( "Requesting user info from SAAS...\n" );

	if ( opt_all_members && opt_gid > 0 )
		ret = saas_group_info_with_all_members_by_gid( &inst , opt_gid , &gi );
	else if ( opt_all_members && strlen( opt_groupname ) > 0 )
		ret = saas_group_info_with_all_members_by_groupname( &inst , opt_groupname , &gi );
	else if ( opt_members && opt_gid > 0 )
		ret = saas_group_info_with_members_by_gid( &inst , opt_gid , &gi );
	else if ( opt_members && strlen( opt_groupname ) > 0 )
		ret = saas_group_info_with_members_by_groupname( &inst , opt_groupname , &gi );
	else if ( opt_gid > 0 )
		ret = saas_group_info_by_gid( &inst , opt_gid , &gi );
	else if ( strlen( opt_groupname ) > 0 )
		ret = saas_group_info_by_groupname( &inst , opt_groupname , &gi );

	if ( opt_log_level == LOG_DEBUG || ret != SAAS_OP_SUCCESS )
		printf( "saas_group_info_with_all_members_by_gid request returned: (%d) %s\n" , ret , saaserror( ret ) );

	if ( opt_log_level != LOG_CRIT && ret == SAAS_OP_SUCCESS )
	{
		printf( "    groupname = %s\n" , gi->groupname   );
		printf( "          gid = %u\n" , gi->gid         );
		uint16_t k;
		for ( k = 0 ; k < gi->num_members ; k++ )
		{
			if ( gi->members[k]->type == SAAS_GROUP_MEMBER_TYPE_USER )
				printf( " member(user) = %d(%s)\n" , gi->members[k]->id , gi->members[k]->name );
			else
				printf( "member(group) = %d(%s)\n" , gi->members[k]->id , gi->members[k]->name );
		}
		free( gi );
	}

	return 0;
}


